#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <cstdlib>
#include <cstdio>
#include <pthread.h>
#include <cstring>
#include <cerrno>
#include <netinet/in.h>
#include <arpa/inet.h>
namespace client
{
    using namespace std;
    pthread_t tid;
    void *sendMessage(void *args)
    {
        while (1)
        {
            // 开启一个线程接受信息
            pthread_detach(pthread_self());
            int *socketfd = static_cast<int *>(args);
            struct sockaddr_in Server;
            char buffer[1024];
            socklen_t len = sizeof(Server);
            int k = recvfrom(*socketfd, buffer, sizeof buffer, 0, (struct sockaddr *)&Server, &len);
            if (k >= 0)
            buffer[k] = 0;
            cout << buffer << endl;
        }
    }
    class udpClient
    {
    public:
        udpClient(uint16_t ServerPort, string ServerIp) : _ServerIp(ServerIp), _ServerPort(ServerPort), _socketfd(-1)
        {
        }
        void Init()
        {
            _socketfd = socket(AF_INET, SOCK_DGRAM, 0);
            if (_socketfd == -1)
            {
                cerr << "Client err" << errno << strerror(errno) << endl;
                exit(2);
            }
            cout << "sucess :" << _socketfd << endl;
            // Client也需要bind，只不过是os来bind，而不是程序员来bind
        }
        void run()
        {
            pthread_create(&tid, nullptr, sendMessage, (void *)&_socketfd);
            struct sockaddr_in peer;
            memset(&peer, 0, sizeof peer);
            peer.sin_family = AF_INET;
            peer.sin_port = htons(_ServerPort);
            peer.sin_addr.s_addr = inet_addr(_ServerIp.c_str());
            string message;
            char buffer[1024];
            while (1)
            {
                cout<<"#";
                fgets(buffer, sizeof buffer, stdin);
                buffer[strlen(buffer) - 1] = 0;
                message = buffer;
                int n = sendto(_socketfd, message.c_str(), message.size(), 0, (struct sockaddr *)&peer, sizeof peer);
            }
        }
        ~udpClient()
        {
        }

    private:
        int _socketfd;
        uint16_t _ServerPort;
        string _ServerIp;
    };
}
